package com.phelon.epdm;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.BooleanUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import com.phelon.systemLink.SessionInfo;
import com.phelon.systemLink.SessionManager;

public abstract class XMLBuilder {

	private String environmentID;
	private Document document;
	private Document responseDocument;
	private List<String> errorMessages;

	/**
	 * Builds and posts XML to create a record through System-link
	 * 
	 * @return success boolean
	 * @author Jessica King, Pete Danfy
	 */
	public boolean doCreate() {
		SessionManager sm = SessionManager.getInstance();
		SessionInfo session = sm.getSessionInfo(environmentID);
		boolean success = false;
		if (session != null) {
			buildCreateXML(session);
			/* post xml */
			String xmlFile = "c:/temp/xml/document.xml";
			serializeXML(xmlFile);

			String response = sm.postXML(document.asXML());
			try {
				success = readResponse(response);
				String responseFile = "c:/temp/xml/response.xml";
				serializeResponseXML(responseFile);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		/* check for success or errors */
		return success;

		/* notify or update */
	}

	/**
	 * Parses the response checking for errors. Loads error messages into List -
	 * errorMessages.
	 * 
	 * @author - Jessica King, Pete Danfy
	 * @return - success boolean
	 * @param -
	 *            response String
	 */

	public boolean readResponse(String response) throws DocumentException {
		responseDocument = DocumentHelper.parseText(response);

		XPath xpathSelector = DocumentHelper.createXPath("//CreateResponse");
		boolean success = false;
		List<Element> results = xpathSelector.selectNodes(responseDocument);
		if (results != null && !results.isEmpty()) {
			success = true;
			for (Element e : results) {
				String objectName = e.attributeValue("name");
				if (BooleanUtils.toBoolean(e.attributeValue("actionSucceeded"))) {
					System.out.println("Action succeeded for key '" + objectName + "'");
				} else {
					System.out.println("Action was not successful for item '" + objectName + "'");
					success = false;
				}
			}
		}
		if (success == false) {
			errorMessages = new ArrayList<String>();
			XPath xpathSelector2 = DocumentHelper.createXPath("//Response/Exception/Message/Text");
			List<Element> results2 = xpathSelector2.selectNodes(responseDocument);
			for (Element e2 : results2) {
				errorMessages.add(e2.getText());
			}
			XPath xpathSelector3 = DocumentHelper.createXPath("//CreateResponse/Exception/Message");
			List<Element> results3 = xpathSelector3.selectNodes(responseDocument);
			for (Element e3 : results3) {
				String messageBox = e3.elementText("Text");
				if (e3.element("DetailedText") != null) {
					messageBox = messageBox + " - - " + e3.elementText("DetailedText");
				}
				errorMessages.add(messageBox);
			}

		} else {
			readSuccessfulResponse(responseDocument);
		}
		return success;
	}

	public abstract void buildCreateXML(SessionInfo theSession);

	/**
	 * Writes the XML request to the file passed in through the parameter.
	 * 
	 * @param xmlFile
	 *            String
	 * @author Jessica King
	 */
	private void serializeXML(String xmlFile) {
		OutputFormat outformat = OutputFormat.createPrettyPrint();
		outformat.setEncoding("ISO-8859-1");
		OutputStream out;
		try {
			out = FileUtils.openOutputStream(new File(xmlFile));
			XMLWriter writer = new XMLWriter(out, outformat);
			writer.write(document);
			writer.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Writes the response to the file passed in through the parameter.
	 * 
	 * @author Pete Danfy
	 * @param responseFile
	 *            String
	 */
	private void serializeResponseXML(String responseFile) {
		OutputFormat outformat = OutputFormat.createPrettyPrint();
		outformat.setEncoding("ISO-8859-1");
		OutputStream out;
		try {
			out = FileUtils.openOutputStream(new File(responseFile));
			XMLWriter writer = new XMLWriter(out, outformat);
			writer.write(responseDocument);
			writer.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public abstract void readSuccessfulResponse(Document responseDocument);

	/**
	 * @return - List, String errorMessages. Contains errors returned in the
	 *         response XML.
	 * @author - Pete Danfy
	 */

	public List<String> getErrorMessages() {
		return errorMessages;
	}

	public String getEnvironmentID() {
		return environmentID;
	}

	public void setEnvironmentID(String environmentID) {
		this.environmentID = environmentID;
	}

	public Document getDocument() {
		return document;
	}

	public void setDocument(Document document) {
		this.document = document;
	}

	public Document getResponseDocument() {
		return responseDocument;
	}

	public void setResponseDocument(Document responseDocument) {
		this.responseDocument = responseDocument;
	}

	public void setErrorMessages(List<String> errorMessages) {
		this.errorMessages = errorMessages;
	}
}
